import cv2

show_image = False


# Function to handle button callback
def on_button_click(val):
    global show_image
    show_image = bool(val)
    if show_image:
        cv2.destroyAllWindows()
        p.release()
    else:
        cv2.imshow('image', img)


if __name__ == '__main__':
    p = cv2.VideoCapture(0)
    face_detector = cv2.CascadeClassifier("./haarcascade_frontalface_alt.xml")
    smile_detector = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_smile.xml')
    num1 = 1
    num2 = 1
    isWrite = False
    isImage = False
    isMosaic = False# 是否打开,按键x控制人脸马赛克,初始不显示，点击x打开马赛克，再次点击取消
    isGray = False
    cv2.namedWindow('image')
    cv2.createTrackbar('Show Image', 'image', 0, 1, on_button_click)

    while True:
        flag, img = p.read()
        if not flag:
            break

        gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
        faces = face_detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)



        cv2.putText(img, f'Faces: {len(faces)}', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)


        for (x, y, w, h) in faces:
            face = img[y:y + h, x:x + w]
            if not isMosaic:
                cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = img[y:y + h, x:x + w]
            smiles = smile_detector.detectMultiScale(roi_gray, scaleFactor=1.8, minNeighbors=20)
            for (sx, sy, sw, sh) in smiles:
                cv2.rectangle(roi_color, (sx, sy), (sx + sw, sy + sh), (0, 0, 255), 2)
                cv2.putText(img, 'Smile Detected', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36, 255, 12), 2)

            if isWrite:
                cv2.imwrite("./face/%d.jpg" % (num1), face)
                num1 += 1
                isWrite = False

            if isImage:
                cv2.imwrite("./img/%d.jpg" % (num2), img)
                num2 += 1
                isImage = False

        height, width, _ = img.shape
        cv2.putText(img, f'Resolution: {width}x{height}', (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)


        if isMosaic:
            for (x, y, w, h) in faces:
                face = img[y:y + h, x:x + w]
                step = 20
                face = face[::step, ::step]
                fh, fw = face.shape[:2]
                for i in range(fh):
                    for j in range(fw):
                        img[y + i * step:y + (i + 1) * step, x + j * step:x + (j + 1) * step] = face[i, j]

        if isGray:
            img=cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)

        cv2.imshow('image', img)

        key = cv2.waitKey(25)
        if  key == ord('x'):
            isMosaic = not isMosaic
        elif key == ord('q'):
            break
        elif key == ord('w'):
            isWrite = True
        elif key == ord('e'):
            isImage = True
        elif key ==ord('r'):
            isGray = not isGray


    cv2.destroyAllWindows()
    p.release()